<?

class Smutty_GPG_SignedMessage {

	var $original, $msgHeaders, $sigHeaders, $msgBody, $sigBody;

	/**
	 *  constructor
	 *
	 *  @param [data] the signed message data
	 *
	 */

	function Smutty_GPG_SignedMessage( $data ) {
		$this->original = $data;
		$this->msgHeaders = array();
		$this->sigHeaders = array();
		$this->msgBody = '';
		$this->sigBody = '';
		$this->processMessage( $data );
	}

	/**
	 *  returns this messages text, all of it
	 *
	 *  @return String
	 *
	 */

	function getText() {
		return $this->original;
	}

	/**
	 *  processes a complete signed message block
	 *
	 *  @param [data] the message data
	 *
	 */

	function processMessage( $data ) {

		$sigStart = '-----BEGIN PGP SIGNATURE-----';
		$matches = preg_split(
			"/$sigStart/", $data
		);

		// the message section
		$this->processSection( 'SIGNED MESSAGE',
			$matches[0], $this->msgBody,
			$this->msgHeaders
		);

		// the sig section
		$this->processSection( 'SIGNATURE',
			$sigStart . $matches[1],
			$this->sigBody, $this->sigHeaders
		);

	}

	/**
	 *  processes a section of a message (start tag, headers and body)
	 *
	 *  @param [tag] the tag we're expecting
	 *  @param [data] the section data
	 *  @param [body] section body variable to set
	 *  @param [headers] section headers to set
	 *
	 */

	function processSection( $tag, $data, &$body, &$headers ) {

		$lines = preg_split( '/\n/', $data );

		// check start line matches
		$line = array_shift( $lines );
		if ( !preg_match("/-----BEGIN PGP $tag-----/",$line) )
			return;

		// now start matching headers
		while ( $lines ) {
			$line = array_shift( $lines );
			if ( preg_match('/^$/',$line) ) break;
			preg_match( '/^(\w+): (.+)$/', $line, $matches );
			if ( Smutty_GPG_SignedMessage::isValidHeader($matches[1],$matches[2]) )
				$headers[ $matches[1] ] = $matches[2];
		}

		// now the data body
		foreach ( $lines as $line ) {
			if ( preg_match('/^-----END PGP/',$line) ) break;
			$body .= $line;
		}

	}

	/**
	 *  STATIC
	 *
	 *  checks a header is ok
	 *
	 *  @param [name] the name to check
	 *  @param [value] the value to check
	 *  @return boolean
	 *
	 */

	function isValidHeader( $name, $value ) {

		// check name
		$names = array(
			Version => 1,
			Comment => 1,
			MessageID => 1,
			Hash => 1,
			Charset => 1
		);
		if ( !$names[$name] )
			return false;

		// check value
		// TODO?  what's valid/invalid?

		// tests passed, all ok
		return true;

	}

	/**
	 *  returns the body of the request
	 *
	 */

	function getMessageBody() {
		return $this->msgBody;
	}

}

?>